package ws

import (
	"log"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

// Client 表示一个WebSocket客户端
type Client struct {
	Conn      *websocket.Conn
	Send      chan []byte
	LastAlive time.Time // 新增心跳检测
}

// WebSocketManager 管理所有WebSocket连接
type WebSocketManager struct {
	clients    map[string]*Client // 用户ID到Client的映射
	broadcast  chan Message       // 广播消息通道
	register   chan *Client       // 注册通道
	unregister chan *Client       // 注销通道
	mu         sync.Mutex         // 互斥锁，保证线程安全
}

// Message 表示聊天消息
type Message struct {
	Sender    string `json:"sender"`
	Recipient string `json:"recipient"`
	Content   string `json:"content"`
}

// NewWebSocketManager 创建一个新的WebSocket管理器
func NewWebSocketManager() *WebSocketManager {
	return &WebSocketManager{
		clients:    make(map[string]*Client),
		broadcast:  make(chan Message),
		register:   make(chan *Client),
		unregister: make(chan *Client),
	}
}

// RegisterClient 注册一个新的客户端
func (m *WebSocketManager) RegisterClient(userID string, conn *websocket.Conn) {
	m.mu.Lock()
	defer m.mu.Unlock()

	client := &Client{
		Conn: conn,
		Send: make(chan []byte, 256),
	}

	m.clients[userID] = client

	go client.writePump()
	go client.readPump(m, userID)
}

// UnregisterClient 注销客户端
func (m *WebSocketManager) UnregisterClient(userID string) {
	m.mu.Lock()
	defer m.mu.Unlock()

	if client, ok := m.clients[userID]; ok {
		close(client.Send)
		delete(m.clients, userID)
	}
}

// SendMessageToUser 向特定用户发送消息
func (m *WebSocketManager) SendMessageToUser(sender, recipient, content string) {
	m.mu.Lock()
	defer m.mu.Unlock()

	msg := Message{
		Sender:    sender,
		Recipient: recipient,
		Content:   content,
	}

	// 打印当前所有连接的客户端
	log.Printf("当前在线用户列表:")
	for id, client := range m.clients {
		log.Printf("- %s (连接状态: %v)", id, client.Conn != nil)
	}

	if client, ok := m.clients[recipient]; ok {
		client.Send <- []byte(msg.Content)
		log.Printf("消息已发送给 %s", recipient)
	} else {
		log.Printf("错误：接收者 %s 不在线", recipient) // 检查是否打印这句
	}
}

// readPump 从WebSocket连接读取消息
func (c *Client) readPump(m *WebSocketManager, userID string) {
	defer func() {
		m.UnregisterClient(userID)
		c.Conn.Close()
	}()

	c.LastAlive = time.Now()
	ticker := time.NewTicker(30 * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			if time.Since(c.LastAlive) > 1*time.Minute {
				return
			}
		default:
			_, message, err := c.Conn.ReadMessage()
			if err != nil {
				if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
					log.Printf("error: %v", err)
				}
				return
			}
			c.LastAlive = time.Now()
			log.Printf("Received message from %s: %s", userID, string(message))
		}
	}
}

// writePump 向WebSocket连接写入消息
func (c *Client) writePump() {
	defer func() {
		c.Conn.Close()
	}()

	for {
		select {
		case message, ok := <-c.Send:
			if !ok {
				// 通道关闭
				c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}

			w, err := c.Conn.NextWriter(websocket.TextMessage)
			if err != nil {
				return
			}
			w.Write(message)

			// 可以在这里添加更多消息
			n := len(c.Send)
			for i := 0; i < n; i++ {
				w.Write(<-c.Send)
			}

			if err := w.Close(); err != nil {
				return
			}
		}
	}
}
